package gomz.pres;

import java.util.ArrayList;

import gomz.ClientToServerCon;
import gomz.GlobalRes;
import gomz.res.Category;
import gomz.res.Hexagram;
import gomz.res.Question;
import gomz.res.QuestionCore;

/**
 * Diese Klasse ist die Superklasse der Models MQuestion und MVerwaltung. Sie Beinhaltet die Logik und Variablen, welche von
 * beiden Subklassen verwendet werden.
 * @author Murillo
 * @author Dilji
 */
public class ModelMain {
	// ********************************************************************************
	// Variablen
	// ********************************************************************************
	protected ClientToServerCon con;						//Verbindungsklasse um mit dem Server zu Kommunitieren
	protected ArrayList<Category> categories;				//Alle Kategorien
	protected ArrayList<QuestionCore> questionCoresAll;		//Alle Fragestellungen
	protected ArrayList<QuestionCore> questionCoresUsed;	//Die Fragestellungen, welche dem Benutzer angezeigt werden
	private Hexagram hexagram;								//Das aktuell verwendete Hexagram
	private Question question = null;						//wird nur im Model Question verwendet, jedoch auch von einem Controller der Verwaltung benoetigt um redundanten code einzusparen
	// ********************************************************************************
	// Getter/Setter
	// ********************************************************************************
	public Question getQuestion() {
		return question;
	}

	public void setQuestion(Question question) {
		this.question = question;
	}
	
	public Hexagram getHexagram() {
		return hexagram;
	}

	public void setHexagram(Hexagram hexagram) {
		this.hexagram = hexagram;
	}
	
	public ArrayList<Category> getCategories() {
		return categories;
	}
	
	public void setCategories(ArrayList<Category> categories) {
		this.categories = categories;
	}
	
	public ClientToServerCon getCon() {
		return con;
	}

	public void setCon(ClientToServerCon con) {
		this.con = con;
	}
	
	public ArrayList<QuestionCore> getQuestionCoresUsed() {
		return questionCoresUsed;
	}
	
	public void setQuestionCoresUsed(ArrayList<QuestionCore> questionCoresUsed) {
		this.questionCoresUsed = questionCoresUsed;
	}
	
	public ArrayList<QuestionCore> getQuestionCoresAll() {
		return questionCoresAll;
	}

	public void setQuestionCoresAll(ArrayList<QuestionCore> questionCoresAll) {
		this.questionCoresAll = questionCoresAll;
	}

	// ********************************************************************************
	// Konstruktor
	// ********************************************************************************
	/**
	 * Konstruktor fuer ModelMain
	 */
	public ModelMain(){
		//Globale verbindungsklasse
		con = GlobalRes.getCon();
	}
	
	// ********************************************************************************
	// Methoden
	// ********************************************************************************
	/**
	 * Diese Methode hohlt die zu oeffnende Fragestellung vom Server.
	 * @param id Die ID der gewuenschten Fragestellung
	 * @return Boolean ob die Frage geoeffnet werden konnte
	 */
	public boolean openQuestion(int id){
		boolean re;
		setQuestion(con.questionGet(id));
		if(getQuestion()!=null) 	re = true;
		else				re = false;
		return(re);
	}
	
     
	
	/**
	 * Diese Methode gibt einen Stringarray mit den Namen aller Kategorie zurueck
	 * @return ArrayList<String> Alle Kategorienamen als Strings
	 */
	public String[] getCategoryList(){
		return(getCategoryListFromArraylist(categories));
	}
	
	/**
	 * Diese Methode wandelt eine Arraylist von Kategorien in einen Stringarray mit den Namen der Kategorien um
	 * @param catList ArrayList mit den umzuwandelnden Kategorien
	 * @return String Array mit den Namen der Kategorien
	 */
	public String[] getCategoryListFromArraylist(ArrayList<Category> catList){
		String[] re = new String[catList.size()];
		
		for(int i = 0; i < re.length; i++){
			re[i] = catList.get(i).getName();
		}
		
		return(re);
	}
	
	/**
	 * Diese Methode erstellt einen Stringarray mit allen momentan verwendeten Titeln der Fragestellungen
	 * @return Stringarray mit den Titeln der momentan verwendeten Fragestellungen
	 */
	public String[] getQuestionList(){
		return(questionCoreListToStringArray(getQuestionCoresUsed()));
	}
	
	/**
	 * Diese Methode filtert die Fragestellung nach den Uebergebenen Kategorien. Alle Fragestellungen, die einer der uebergebenen
	 * Kategorien angehoeren, werden in die Lister der verwendeten Fragestellungen gesetzt.
	 * @param selectedCategories Indices der Kategorien, nach denen gefiltert werden soll
	 */
	public void filterQuestionToUse(int[] selectedCategories){
		ArrayList<Category> selectedCategoryList = new ArrayList<Category>();
		for(int cat : selectedCategories){
			selectedCategoryList.add(categories.get(cat));
		}
		filterQuestionToUse(selectedCategoryList);
	}
	
	/**
	 * Diese Methode filtert die Fragestellung nach den Uebergebenen Kategorien. Alle Fragestellungen, die einer der uebergebenen
	 * Kategorien angehoeren, werden in die Lister der verwendeten Fragestellungen gesetzt.
	 * @param selectedCategories ArrayListe mit den Kategorien, nach denen gefiltert werden soll
	 */
	public void filterQuestionToUse(ArrayList<Category> selectedCategories){
		ArrayList<QuestionCore> questionToUse = new ArrayList<QuestionCore>();
		
		//falls keine Kategorie angegeben wird, sollen alle Fragen verwendet werden
		if(selectedCategories.size() == 0){
			questionToUse = getQuestionCoresAll();
		}
		else{
			//kein contains(category) da nicht das selbe objekt von der Datenbank erhalten wird
			//jede Frage
			for(QuestionCore q : questionCoresAll){
				//jede Kategorie der Frage
				for(Category qCat : q.getCat()){
					//jede selektierte Kategorie
					for(Category cat : selectedCategories){
						if(qCat.getId() == cat.getId()){
							if(!questionToUse.contains(q)){
								questionToUse.add(q);
							}
						}
					}
				}
			}
		}
		
		setQuestionCoresUsed(questionToUse);
	}
		
	/**
	 * Diese Methode wandelt eine ArrayListe von QuestionCores in einen Stringarray mit den Titeln der Fragestellungen um.
	 * Falls die Methode Public ist und nicht dem angemeldeten Benutzer gehoehrt, wird vor den Titel ein [P] hinzugefuegt.
	 * @param questionCores Die umzuwandelnden QuestionCores
	 * @return Sting[] Die Titel der Fragestellungen
	 */
	private String[] questionCoreListToStringArray(ArrayList<QuestionCore> questionCores){
		String[] re = new String[questionCores.size()];
		for(int i = 0; i < re.length; i++){
			QuestionCore qc = questionCores.get(i);
			String tmpRe = "";
			if (qc.isIsPublic() && qc.getUser().getId() != GlobalRes.getActivUser().getId()){
				tmpRe += "[P] ";
			}
			tmpRe += qc.getTitle();
			re[i] = tmpRe;
		}
		
		return (re);
	}
	
	/**
	 * Diese Methode schickt ein uebergebenes Hexagramm dem Server um es zu speichern
	 * @param hex Das zu speichernde Hexagram
	 * @return Boolean ob der Vorgang durchgefuehrt werden konnte
	 */
	public boolean saveHexagram(Hexagram hex, boolean oriTxtChange){
		return (con.hexagramSave(hex, oriTxtChange));
	}
	
	//Author Dilji
	/**
	 * Diese Methode erstellt eine neue Kategorie mit dem uebergeben Namen und fuegt sie
	 * der Kategorieleiste bei
	 * @param catNameToAdd Name der neuen Kategorie
	 * @return Boolean ob der Vorgang durchgefuehrt werden konnte
	 */
	public boolean addNewCategory(String catNameToAdd){
		Category re = null;
		// neue Kategorie erstellen
		Category newCat = new Category();
		newCat.setName(catNameToAdd);
		
		re = con.catSave(newCat);
		if(re != null){
			// Kategorie hinzufuegen
			this.getCategories().add(re);
		}
		
		return (re==null?false:true);
	}
}
